package InternetHax;

/*
 * This work is part of the 59Pixels Library
 *
 * 59Pixels J2ME Library by Alan Clelland - 59Pixels is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
 * Based on a work at www.59pixels.com. 
 *
 * You are free to edit, sell and redistribute this file as much as you want as long as you
 * keep this disclaimer in the file where ever you distribute the code.
 * 
 */
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;


/**
 * Free font library from www.59pixels.com. Much better than default built-in fonts, allowing for transparencty and coloring of text.
 *   
 */
public class Font59 {

    private int imgHeight;
    private char[] chars;
    private byte[] charsWidth;
    private Image[] charImage;
    private Image[][] changedImage;
    int resultWidth;
    int maximumNumberOfFonts = 3;
    /**
     * Crate  of class
     */
    public Font59(String imgFile) {
        try {
            initialize(imgFile);
        } catch (Exception ee) {
            System.out.println("Could Not Create Font");
            ee.printStackTrace();
        }
    }

    /**
     * Initialize data, load information about characters from file
     *
     * @throws IOException
     */
    public void createColouredText(String text, int colour) {

    }

    public void initialize(String fileName) throws IOException {
        Image img = null;
        InputStream is = this.getClass().getResourceAsStream(fileName);
        DataInputStream dis = new DataInputStream(is);
        int len = dis.readInt();
        chars = new char[len];
        charImage = new Image[len];
        charsWidth = new byte[len];
        for (int i = 0; i < len; i++) {
            chars[i] = dis.readChar();
            charsWidth[i] = dis.readByte();
        }
        int imgSize = dis.readInt();
        byte[] tmpBuffer = new byte[imgSize];
        dis.read(tmpBuffer, 0, imgSize);

        img = Image.createImage(tmpBuffer, 0, imgSize);

        if (img != null) {
            imgHeight = img.getHeight();
            int x = 0;
            for (int i = 0; i < len; i++) {
                charImage[i] = Image.createImage(charsWidth[i], imgHeight);
                Graphics g = charImage[i].getGraphics();
                g.setColor(255, 255, 255);
                g.setClip(0, 0, charsWidth[i], imgHeight);
                g.drawImage(img, -x, 0, Graphics.TOP | Graphics.LEFT);
                x += charsWidth[i];
                g = null;

                int[] temp = new int[charImage[i].getWidth() * charImage[i].getHeight()];
                charImage[i].getRGB(temp, 0, charImage[i].getWidth(), 0, 0, charImage[i].getWidth(), charImage[i].getHeight());
                int first = temp[0];
                for (int j = 0; j < temp.length; j++) {
                    if (temp[j] == first) {
                        temp[j] = 0x00ffffff;
                    }
                }
                charImage[i] = Image.createRGBImage(temp, charImage[i].getWidth(), charImage[i].getHeight(), true);
            }
        }
        tmpBuffer = null;
        img = null;
    }

    public void deleteAllFonts()
    {
        changedImage = null;
        System.gc();
    }
    /**
     * Returns position of char in CHAR_TAB array
     *
     * @param ch character to find
     * @return position of char in characters array
     */
    public int GetFontHeight() {
        return imgHeight;
    }

    public int GetStringWidth(String text) {
        int width = 0;
        for (int i = 0; i < text.length(); i++) {
            int val = charIndex(text.charAt(i));
            if (val != -1) {
                width += charsWidth[val];
            }
        }

        return width;
    }
    
    public static int HCENTER = 1;
    public static int RIGHT = 2;
    public static int LEFT = 0;
    public static int TOP = 1;
    public static int BOTTOM = 2;
    public static int VCENTER = 3;
    int prevLen = -1;
    int[] indxs;
    String prevStr = "*'#";
    int val;
    int width;

    synchronized public void PrintString(Graphics g, int x, int y, String text, int hPos, int VPos) {
        PrintString(g, x, y, text, hPos, VPos, -1);
    }

    synchronized public void PrintString(Graphics g, int x, int y, String text, int hPos, int VPos, int fontNum) {
        
        if(fontNum != -1 && (changedImage == null ||changedImage[fontNum] == null))
        {
            fontNum = -1;
        }
        
        if (text == null) {
            return;
        }
        
        if (!prevStr.equals(text)) {
            width = 0;
            int txtLength = text.length();

            if (txtLength != prevLen) {
                indxs = new int[txtLength];
            }

            prevLen = txtLength;
         
            for (int i = 0; i < txtLength; i++) 
            {
                if(text.charAt(i) == '|')
                {
                        indxs[i] = -10;
                }
                else
                {
                    val = charIndex(text.charAt(i));
                    indxs[i] = val;
                    if (val >=0) {
                        width += charsWidth[val];
                    }
                }
            }

            if (hPos == HCENTER) {
                x -= width / 2;
            }
            if (hPos == RIGHT) {
                x -= width;
            }
            
            if (VPos == BOTTOM) {
                y -= imgHeight;
            }
            if (VPos == VCENTER) {
                y -= imgHeight / 2;
            }
        }

        for (int i = 0; i < indxs.length; i++) {
            val = indxs[i];
            if(val == -10)
            {
                if(enableChange == 0)continue;
                
                if(fontNum == -1)
                {
                    fontNum = previousFont;
                    leftOnSpecial = 1;
                }
                else if(fontNum != -1)
                {
                    previousFont = fontNum;
                    fontNum = -1;
                    leftOnSpecial = 0;    
                }
            }
            else if (val != -1) {

                if (fontNum == -1) {
                    g.drawImage(charImage[val], x, y, 0);
                } else {
                    g.drawImage(changedImage[fontNum][val], x, y, 0);
                }
                x += charsWidth[val];
            }
        }
    }
    
    int previousFont = 1;
    int enableChange = 1;
    byte leftOnSpecial =0;
    int charIndexI;

    private int charIndex(char ch) {
        charIndexI = -1;
        for (charIndexI = 0; charIndexI < chars.length; charIndexI++) {
            if (chars[charIndexI] == ch) {
                break;
            }
        }
        if (charIndexI == chars.length) {
            charIndexI = -1;
        }
        return charIndexI;
    }

    /**
     * Gets font height
     *
     * @return font height in pixels
     */
    public int getFontHeight() {
        return imgHeight;
    }

    /**
     * Gets the width of specified character
     *
     * @param ch - the character to be measured
     * @return width of the given character
     */
    public int charWidth(char ch) {
        int index = charIndex(ch);
        if (index != -1) {
            return charsWidth[index];
        } else {
            return 0;
        }
    }

    /**
     * Gets the total width for the specified string
     *
     * @param str the string to be measured
     * @return the total width
     */
    public int stringWidth(String str) {
        int sum = 0;
        return sum;
    }

    public int makeNewFont(int newColour) {
        return makeNewFont(newColour, false, 0);
    }

    public int makeNewFont(int newColour, int boldColour) {
        return makeNewFont(newColour, true, boldColour);
    }

    public int makeGradientFont(int topColour, int bottomColour) {
        int fontNum;
        if (changedImage == null) {
            changedImage = new Image[3][];
        }

        for (fontNum = 0; fontNum < changedImage.length; fontNum++) {
            if (changedImage[fontNum] == null) {
                break;
            }
        }
        changedImage[fontNum] = new Image[charImage.length];
        for (int i = 0; i < charImage.length; i++) {
            changedImage[fontNum][i] = changeToGradient(topColour, bottomColour, charImage[i]);
        }

        return fontNum;
    }

    public int makeNewFont(int newColour, boolean bold, int boldColour) {
        int fontNum;
        if (changedImage == null) {
            changedImage = new Image[maximumNumberOfFonts][];
        }

        for (fontNum = 0; fontNum < changedImage.length; fontNum++) {
            if (changedImage[fontNum] == null) {
                break;
            }
        }

        changedImage[fontNum] = new Image[charImage.length];
        for (int i = 0; i < charImage.length; i++) {
            changedImage[fontNum][i] = changeColour(newColour, i);

            if (bold) {
                changedImage[fontNum][i] = makeBold(changedImage[fontNum][i], newColour, boldColour);
            }
        }
        return fontNum;
    }
    int[] newColourArray;
    int newColourCount;
    int originalColour = 0xffffffff;
    public Image changeColour(int colour, int i) {
        if (newColourArray == null || newColourArray.length != charImage[i].getWidth() * charImage[i].getHeight()) {
            newColourArray = new int[charImage[i].getWidth() * charImage[i].getHeight()];
        }

        charImage[i].getRGB(newColourArray, 0, charImage[i].getWidth(), 0, 0, charImage[i].getWidth(), charImage[i].getHeight());

        for (newColourCount = 0; newColourCount < newColourArray.length; newColourCount++) {
            if (newColourArray[newColourCount] == originalColour) {
                newColourArray[newColourCount] = colour;
            }
        }
        return Image.createRGBImage(newColourArray, charImage[i].getWidth(), charImage[i].getHeight(), true);
    }

    public Image changeToGradient(int topColour, int bottomColour, Image toMake) {
        int rgb = topColour;
        int r1 = (rgb >> 16) & 0xff;
        int g1 = (rgb >> 8) & 0xff;
        int b1 = rgb & 0xff;

        rgb = bottomColour;
        int r2 = (rgb >> 16) & 0xff;
        int g2 = (rgb >> 8) & 0xff;
        int b2 = rgb & 0xff;

        int rstep = (r2 - r1) / imgHeight;
        int gstep = (g2 - g1) / imgHeight;
        int bstep = (b2 - b1) / imgHeight;

        newColourArray = new int[toMake.getWidth() * toMake.getHeight()];

        toMake.getRGB(newColourArray, 0, toMake.getWidth(), 0, 0, toMake.getWidth(), toMake.getHeight());
        int[][] image2d = new int[toMake.getWidth()][toMake.getHeight()];
        for (int y = 0; y < toMake.getHeight(); y++) {
            for (int x = 0; x < toMake.getWidth(); x++) {

                if (newColourArray[(x) + (y * toMake.getWidth())] == originalColour) {
                    image2d[x][y] = (0xff << 24) | (r1 << 16) | (g1 << 8) | b1;
                }
            }
            r1 += rstep;
            g1 += gstep;
            b1 += bstep;
        }

        for (int y = 0; y < toMake.getHeight(); y++) {
            for (int x = 0; x < toMake.getWidth(); x++) {
                newColourArray[(x) + (y * toMake.getWidth())] = image2d[x][y];
            }
        }
        return Image.createRGBImage(newColourArray, toMake.getWidth(), toMake.getHeight(), true);
    }

    public Image makeBold(Image toMake, int colour, int boldColour) {

        Image temp = Image.createImage(toMake.getWidth() + 2, toMake.getHeight() + 2);
        Graphics tempG = temp.getGraphics();
        if (colour == 0xffffffff) {
            tempG.setColor(0xffff0000);
            tempG.fillRect(0, 0, temp.getWidth(), temp.getHeight());
        } else {

        }
        tempG.drawImage(toMake, 1, 1, 0);


        newColourArray = new int[temp.getWidth() * temp.getHeight()];
        temp.getRGB(newColourArray, 0, temp.getWidth(), 0, 0, temp.getWidth(), temp.getHeight());
        for (int i = 0; i < newColourArray.length; i++) {
            if (newColourArray[i] == 0xffffffff) {
                newColourArray[i] = 0x00000000;
            }
        }
        toMake = Image.createRGBImage(newColourArray, temp.getWidth(), temp.getHeight(), true);
        newColourArray = null;

        newColourArray = new int[toMake.getWidth() * toMake.getHeight()];

        toMake.getRGB(newColourArray, 0, toMake.getWidth(), 0, 0, toMake.getWidth(), toMake.getHeight());
        int[][] image2d = new int[toMake.getWidth()][toMake.getHeight()];
        for (int y = 0; y < toMake.getHeight(); y++) {
            for (int x = 0; x < toMake.getWidth(); x++) {
                image2d[x][y] = newColourArray[(x) + (y * toMake.getWidth())];
            }
        }

        for (int y = 0; y < toMake.getHeight() - 1; y++) {
            for (int x = 0; x < toMake.getWidth() - 1; x++) {

                if (image2d[x][y] == 0x00000000 && image2d[x + 1][y] != 0x00000000) {
                    image2d[x][y] = boldColour;
                }
                if (image2d[x][y] == 0x00000000 && image2d[x][y + 1] != 0x00000000) {
                    image2d[x][y] = boldColour;
                }
            }
        }

        for (int y = toMake.getHeight() - 1; y > 0; y--) {
            for (int x = toMake.getWidth() - 1; x > 0; x--) {

                if (image2d[x][y] == 0x00000000 && image2d[x - 1][y] != 0x00000000) {
                    image2d[x][y] = boldColour;
                }
                if (image2d[x][y] == 0x00000000 && image2d[x][y - 1] != 0x00000000) {
                    image2d[x][y] = boldColour;
                }
            }
        }

        for (int y = 0; y < toMake.getHeight(); y++) {
            for (int x = 0; x < toMake.getWidth(); x++) {
                newColourArray[(x) + (y * toMake.getWidth())] = image2d[x][y];
            }
        }
        return Image.createRGBImage(newColourArray, toMake.getWidth(), toMake.getHeight(), true);
    }

    public static int getRGB(int r, int g, int b) {
        return (0xff << 24) | (r << 16) | (g << 8) | b;
    }
}






